(library (grammar)
  (export SPACE
          RULE-END
          CONTAINMENT-SEPARATOR
          NUMBER
          WORD
          SINGULAR-OR-PLURAL-BAG
          NO-BAG
          COUNT
          COLOR-MOD
          COLOR
          CONTAINER
          CONTAINMENT-POSSIBILITY
          CONTAINMENTS
          RULE)
  (import
    (except (rnrs base) let-values)
    (only (guile) lambda* λ)
    (ice-9 peg)))


(define-peg-pattern SPACE none " ")
(define-peg-pattern RULE-END none ".")
(define-peg-pattern CONTAINMENT-SEPARATOR none ",")
(define-peg-pattern NUMBER body (* (range #\0 #\9)))
(define-peg-pattern WORD body (+ (range #\a #\z)))
(define-peg-pattern SINGULAR-OR-PLURAL-BAG none (or "bags" "bag"))
(define-peg-pattern NO-BAG none "no other bags")
(define-peg-pattern COUNT all NUMBER)
(define-peg-pattern COLOR-MOD all WORD)
(define-peg-pattern COLOR all WORD)
(define-peg-pattern CONTAINER all (and COLOR-MOD SPACE COLOR))

(define-peg-pattern CONTAINMENT-POSSIBILITY all
  (and COUNT SPACE
       COLOR-MOD SPACE
       COLOR SPACE
       SINGULAR-OR-PLURAL-BAG))

(define-peg-pattern CONTAINMENTS all
  (or (and (* (and CONTAINMENT-POSSIBILITY CONTAINMENT-SEPARATOR SPACE))
           (and CONTAINMENT-POSSIBILITY RULE-END))
      NO-BAG RULE-END))

(define-peg-pattern RULE all
  (and CONTAINER SPACE
       "bags" SPACE
       "contain" SPACE
       CONTAINMENTS))
